#ifndef __SESSION_DESCRIPTION_H
#define __SESSION_DESCRIPTION_H
#include <string>
#include <vector>
#include <memory>
#include <rtc_base/rtc_certificate.h>
#include <rtc_base/ssl_fingerprint.h>
#include "ice/candidate.h"

#include "ice/ice_def.h"
#include "ice/ice_credentials.h"
#include "pc/codec_info.h"
#include "pc/stream_params.h"
namespace xrtc
{

    enum class SdpType
    {

        kOffer = 0,
        kAnswer = -1,
    };
    enum class MediaType
    {
        MEDIA_TYPE_AUDIO,
        MEDIA_TYPE_VIDEO,
    };
    enum class RtpDirection
    {

        kSendRecv,
        kSendOnly,
        kRecvOnly,
        kInactive

    };

    class MediaContentDescription // 公共属性
    {
    public:
        virtual ~MediaContentDescription() {}
        virtual MediaType Type() = 0;
        virtual std::string Mid() = 0;
        const std::vector<std::shared_ptr<CodecInfo>> &GetCodec() const
        {
            return codecs_;
        }
        RtpDirection Direction() { return direction_; }
        void SetDirection(RtpDirection direction) { direction_ = direction; }
        bool RtcpMux() { return rtcp_mux_; }
        void SetRtcpMux(bool mux) { rtcp_mux_ = mux; }
        void AddCandidates(const std::vector<Candidate> &candidates) { candidates_ = candidates; }
        const std::vector<Candidate> &Candidates() { return candidates_; }
        const std::vector<StreamParams> &Streams() { return send_streams_; }
        void AddStream(const StreamParams &stream)
        {
            send_streams_.push_back(stream);
        }

    protected:
        std::vector<std::shared_ptr<CodecInfo>> codecs_;
        RtpDirection direction_;
        bool rtcp_mux_ = true;
        std::vector<Candidate> candidates_;
        std::vector<StreamParams> send_streams_;
    };
    class AudioContentDescription : public MediaContentDescription
    {
    public:
        AudioContentDescription();
        MediaType Type() override { return MediaType::MEDIA_TYPE_AUDIO; }
        std::string Mid() override { return "audio"; }
    };
    class VideoContentDescription : public MediaContentDescription
    {
    public:
        VideoContentDescription();
        MediaType Type() override { return MediaType::MEDIA_TYPE_VIDEO; }
        std::string Mid() override { return "video"; }
    };
    // bind
    class ContentGroup
    {
    public:
        ContentGroup(const std::string &semantics) : semantics_(semantics) {}
        ~ContentGroup() {}
        std::string Semantics() const { return semantics_; }
        const std::vector<std::string> &ContentNames() const { return content_names_; }
        void AddContentName(const std::string &content_name);
        bool HasContentName(const std::string &content_name);

    private:
        std::string semantics_;
        std::vector<std::string> content_names_;
    };

    enum ConnectionRole
    {
        NONE = 0,
        ACTIVE,
        PASSIVE,
        ACTPASS,
        HILDCONN

    };
    class TransportDescription
    {
    public:
        std::string mid;
        std::string ice_ufrag;
        std::string ice_pwd;
        std::unique_ptr<rtc::SSLFingerprint> identify_fingerprint;
        ConnectionRole connection_role = ConnectionRole::NONE;
    };
    class SessionDescription
    {
    public:
        SessionDescription(SdpType type);
        ~SessionDescription();
        std::string ToString();

        std::shared_ptr<MediaContentDescription> GetContent(const std::string &mid);
        void AddContent(std::shared_ptr<MediaContentDescription> content);
        // 访问conttent 方法
        const std::vector<std::shared_ptr<MediaContentDescription>> Contents() const { return contents_; }
        void AddGroup(const ContentGroup &group);
        std::vector<const ContentGroup *> GetGroupByName(const std::string &name) const;
        bool AddTransportInfo(const std::string &mid, const IceParameters &ice_param, rtc::RTCCertificate *certificate);
        bool AddTransportInfo(std::shared_ptr<TransportDescription> td);

        std::shared_ptr<TransportDescription> GetTransportInfo(const std::string &mid);

        bool IsBundle(const std::string &mid); // 判断是不是bundle
        std::string GetFirstBundleMid();

    private:
        SdpType sdp_type_;
        std::vector<std::shared_ptr<MediaContentDescription>> contents_; // vector的大小，代表sdp中有多少个m属性行
        std::vector<ContentGroup> content_groups_;
        std::vector<std::shared_ptr<TransportDescription>> transport_infos_;
    };

} // namespace xrtc

#endif
